interface Option {
  el: string
  // 窗口数量
  wnd?: number
  // 底部按钮
  windowsBottom?: number
  // 窗口更多显示
  wnds?: number
  stretchs?: number
}

class LcVido {
  client: any = null
  option: Option
  uuid = ''
  dom: any = ''
  timer: any = -1
  timeStart: any = -1
  timeEnd: any = -1
  constructor (option: any) {
    this.option = option
  }

  private createWndUUid: string = this.createUuid()

  // 视频初始化
  init () {
    return new Promise((resolve, reject) => {
      this.client = new WebSocket('ws://127.0.0.1:16590')
      this.dom = document.querySelector(this.option.el)
      // 连接错误
      this.client.onerror = () => {
        this.openClient().then()
        reject(new Error('ws连接错误'))
      }
      // 链接打开的回调函数
      this.client.onopen = () => {
        this.sendRequest({
          cmd: 'system.connect',
          sequence: this.createWndUUid
        })
        // 监听窗口关闭事件，当窗口关闭时，主动去关闭websocket连接，防止连接还没断开就关闭窗口，server端会抛异常
        window.addEventListener('beforeunload', this.destroy.bind(this))
      }
      // 收到消息的处理函数
      this.client.onmessage = (e: any) => {
        try {
          const data = JSON.parse(e.data)
          console.log(data)

          if (data.uuid && !this.uuid) {
            this.uuid = data.uuid
            this.createWnd()
          }
          if (data.sequence === this.createWndUUid) {
            resolve(this)
          }
        } catch (err) { }
      }
    })
  }

  private openClient () {
    return new Promise((resolve, reject) => {
      window.protocolCheck('LhczWebPlugin://', () => {
        reject(new Error('ws连接错误'))
      }, () => {
        console.log('唤醒成功')
        return this.init()
      })
    })
  }

  // 创建视频
  private createWnd () {
    const msg: any = {
      cmd: 'window.createwnd',
      sequence: this.createWndUUid,
      uuid: this.uuid,
      timestamp: new Date().getTime(),
      rect: this.getRect(),
      wnd: this.option.wnd || parseInt('0x0002'),
      windowsBottom: this.option.windowsBottom || 127,
      wnds: this.option.wnds || 32767,
      stretchs: this.option.stretchs || 15
    }
    this.sendRequest(msg)
    window.addEventListener('resize', this.setWndGeometry.bind(this))
    document.addEventListener('visibilitychange', this.visibilityChange.bind(this), false)
    window.addEventListener('focus', this.focus.bind(this))
  }

  // 浏览器隐藏切换事件
  private visibilityChange () {
    if (document.hidden) {
      this.timeStart = new Date().getTime()
      this.hiddenWnd()
    } else {
      this.timeEnd = new Date().getTime()
      const b = this.getBrowser()
      if (b.chrome || b.mozilla) {
        if (this.timer > 0) {
          clearTimeout(this.timer)
          this.timer = -1
        }
        if (this.timeEnd - this.timeStart < 100) {
          this.timer = setTimeout(() => {
            this.resizeWnd()
            this.setWndGeometry()
            this.showWnd()
          }, 200)
        } else {
          this.showWnd()
          setTimeout(() => {
            this.showWnd()
          }, 100)
        }
      } else {
        this.showWnd()
      }
    }
  }

  // dom获取焦点
  private focus () {
    if (document.hidden) this.showWnd()
  }

  // 播放
  play (url: string, name: string) {
    const msg = {
      cmd: 'window.play',
      sequence: this.createUuid(),
      uuid: this.uuid,
      timestamp: new Date().getTime(),
      info: {
        url,
        wndIndex: -1,
        channelName: name
      }
    }
    this.sendRequest(msg)
  }

  // 刷新播放器
  resizeWnd () {
    const msg = {
      cmd: 'window.updateParent',
      sequence: this.createUuid(),
      uuid: this.uuid,
      timestamp: new Date().getTime()
    }
    this.sendRequest(msg)
  }

  // 重置位置
  setWndGeometry () {
    const msg = {
      cmd: 'window.setWndGeometry',
      sequence: this.createUuid(),
      uuid: this.uuid,
      timestamp: new Date().getTime(),
      rect: this.getRect()
    }
    this.sendRequest(msg)
  }

  // 显示播放器
  showWnd () {
    const msg = {
      cmd: 'window.show',
      sequence: this.createUuid(),
      uuid: this.uuid,
      timestamp: new Date().getTime()
    }
    this.sendRequest(msg)
  }

  // 隐藏播放器
  hiddenWnd () {
    const msg = {
      cmd: 'window.hide',
      sequence: this.createUuid(),
      uuid: this.uuid,
      timestamp: new Date().getTime()
    }
    this.sendRequest(msg)
  }

  // 销毁播放器
  destroy () {
    this.client.close()
  }

  // 获取分辨率比例
  getRatio () {
    let ratio = 1
    const ua = navigator.userAgent.toLowerCase()
    if (window.devicePixelRatio) {
      ratio = window.devicePixelRatio
    } else if (~ua.indexOf('msie')) {
      const screen = window.screen as any
      if ((screen as any).deviceXDPI && screen.logicalXDPI) {
        ratio = screen.deviceXDPI / screen.logicalXDPI
      }
    } else if (window.outerWidth && window.innerWidth) {
      ratio = Math.round(window.outerWidth / window.innerWidth)
    }
    return ratio
  }

  // 获取浏览器信息
  getBrowser () {
    const e = navigator.userAgent.toLowerCase()
    // eslint-disable-next-line no-mixed-operators
    const t = /(edge)[/]([\w.]+)/.exec(e) || /(chrome)[/]([\w.]+)/.exec(e) || /(safari)[/]([\w.]+)/.exec(e) || /(opera)(?:.*version)?[/]([\w.]+)/.exec(e) || /(trident.*rv:)([\w.]+)/.exec(e) || /(msie) ([\w.]+)/.exec(e) || e.indexOf('compatible') < 0 && /(mozilla)(?:.*? rv:([\w.]+))?/.exec(e) || ['unknow', '0']
    t.length > 0 && t[1].indexOf('trident') > -1 && (t[1] = 'msie')
    const n: any = {}
    n[t[1]] = true
    n.version = t[2]
    return n
  }

  // 获取元素位置
  getRect () {
    const ratio = this.getRatio()
    const rect = this.dom.getBoundingClientRect()
    const left = Math.round(rect.left * ratio) + document.documentElement.scrollLeft
    const top = Math.round(rect.top * ratio) + document.documentElement.scrollTop
    const utilsHeight = Math.abs(window.outerHeight - Math.round(window.innerHeight * ratio))
    // const utilsHeight = Math.abs(window.outerHeight - Math.round(window.innerHeight * ratio))
    return {
      top: top + utilsHeight,
      left: left,
      width: Math.round(rect.width * ratio),
      height: Math.round(rect.height * ratio)
    }
  }

  // 生成uuid
  private createUuid () {
    const s = []
    const hexDigits = '0123456789abcdef'
    for (let i = 0; i < 36; i++) {
      s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1)
    }
    s[14] = '4'
    s[19] = hexDigits.substr((+s[19] & 0x3) | 0x8, 1)
    s[8] = s[13] = s[18] = s[23] = '-'

    const uuid = s.join('')
    console.log('uuid->' + uuid)
    return uuid
  }

  // 发送请求
  sendRequest (data: any) {
    this.client.send(JSON.stringify(data))
  }
}

export default LcVido
